﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
using Infrastructure.BaseClasses;
using Infrastructure.Tools;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.ServiceLocation;
using MVVMBasic.Interfaces;
using MVVMBasicRIALibrary.Web.DataModel;
using Infrastructure.Interfaces;

namespace MVVMBasic.ViewModel
{
    public class CustomerListViewViewModel : ViewModelBase
    {
        private ObservableCollection<Dictionary> _dictionariesCollection;
        private ICustomerDetailsView _detailsView;
        private ICollectionView _dictionaries;
        private readonly IRepository<Dictionary> _repository;
        

        public CustomerListViewViewModel()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                _repository = ServiceLocator.Current.GetInstance<IRepository<Dictionary>>();
                _repository.NotifyResultOperation += ResultOperation;
                LoadData();
            }        
        }

        void ResultOperation(object sender, ResultOperationEventArgs e)
        {
            if (e.IsComplete && !e.HasError)
            {
                LoadData();
            }
            else
            {
                ShowErrorMessage(e.Error);
            }
        }

        #region Properties

        public Dictionary SelectedDictionary { get; set; }
        public ObservableCollection<Dictionary> DictionariesCollection
        {
            get { return _dictionariesCollection; }
            set
            {
                _dictionariesCollection = value;
                Dictionaries = new PagedCollectionView(_dictionariesCollection);
                Dictionaries.CurrentChanged += SelectedItemChanged;
                NotifyOfPropertyChange(() => DictionariesCollection);
            }
        }
        public ICollectionView Dictionaries
        {
            get { return _dictionaries; }
            set
            {
                _dictionaries = value;
                NotifyOfPropertyChange(() => Dictionaries);
            }
        }
        #endregion


        private void LoadData()
        {
            IsBusy = true;
            _repository.GetAll(collection =>
            {
                if (collection != null)
                {
                    DictionariesCollection = new ObservableCollection<Dictionary>(collection);
                }
                IsBusy = false;
            });

            //Dictionary dict;

            //repoDict.GetFirst(item => item.Id == 2, (item) =>
            //{
            //    if (item != null)
            //    {
            //        dict = item;
            //    }
            //});

            //IEnumerable<Dictionary> filtered;

            //repoDict.GetByFilter(item => item.Name.Contains("a"), (collection) =>
            //{
            //    if(collection != null)
            //    {
            //        filtered = collection;
            //    }
            //});


            //Dictionary first;

            //repoDict.GetFirst(item => item.Name.Contains("a"), (item) =>
            //{
            //    if (item != null)
            //    {
            //        first = item;
            //    }
            //});
        }

        #region ICommands
        private ICommand _addCommand;
        private ICommand _editCommand;
        private ICommand _deleteCommand;
        private ICommand _groupCommand;
        private ICommand _ungroupCommand;
        private ICommand _sortCommand;

        public ICommand AddCommand
        {
            get { return _addCommand ?? (_addCommand = new DelegateCommand<object>(OnAddCommand)); }
        }
        public ICommand EditCommand
        {
            get { return _editCommand ?? (_editCommand = new DelegateCommand<object>(OnEditCommand)); }
        }
        public ICommand DeleteCommand
        {
            get { return _deleteCommand ?? (_deleteCommand = new DelegateCommand<object>(OnDeleteCommand)); }
        }
        public ICommand GroupCommand
        {
            get { return _groupCommand ?? (_groupCommand = new DelegateCommand<object>(OnGroupCommand)); }
        }
        public ICommand UngroupCommand
        {
            get { return _ungroupCommand ?? (_ungroupCommand = new DelegateCommand<object>(OnUngroupCommand)); }
        }
        public ICommand SortCommand
        {
            get { return _sortCommand ?? (_sortCommand = new DelegateCommand<object>(OnSortCommand)); }
        }
        #endregion

        #region Methods
        private void SelectedItemChanged( object sender, EventArgs e )
        {
            SelectedDictionary = Dictionaries.CurrentItem as Dictionary;
        }
        private void OnAddCommand(object obj)
        {
            ShowDetails(new Dictionary());
        }
        private void OnEditCommand(object obj)
        {
            var dict = obj as Dictionary;
            if (dict != null)
                ShowDetails(dict);
        }
        private void OnDeleteCommand(object obj)
        {
            var dict = obj as Dictionary;
            if (dict != null)
            {
                _repository.Delete(dict);
                _repository.SaveChanges();
            }
        }
        private void OnGroupCommand(object obj)
        {
            Dictionaries.GroupDescriptions.Add(new PropertyGroupDescription("Description"));
        }
        private void OnUngroupCommand(object obj)
        {
            Dictionaries.GroupDescriptions.Clear();
        }
        private void OnSortCommand(object obj)
        {
            Dictionaries.SortDescriptions.Add(new SortDescription("Description",ListSortDirection.Ascending));
        }
        public void ShowDetails(Dictionary dict)
        {
            _detailsView = ServiceLocator.Current.GetInstance<ICustomerDetailsView>();
            if (_detailsView != null)
            {
                var detailsViewViewModel = _detailsView.DataContext as ICustomerDetailsViewViewModel;
                if (detailsViewViewModel != null)
                {
                    var result = new ResultEnumerator(InitializeDetails(dict, detailsViewViewModel));
                    result.Enumerate();
                }
            }
        }
        private IEnumerable<IResult> InitializeDetails(Dictionary dict, ICustomerDetailsViewViewModel customerDetailsViewModel)
        {
            yield return new BackgroundResult(() => customerDetailsViewModel.Initialize(dict, _repository));
            yield return new BackgroundResult(() =>
            {
                customerDetailsViewModel.EditViewClosing += customerDetailsViewModel_EditViewClosing;
            });
            yield return new BackgroundResult(() => Dispatcher.BeginInvoke(() => _detailsView.Show()));
        }
        void customerDetailsViewModel_EditViewClosing(object sender, EventArgs e)
        {
            if (_detailsView != null)
            {
                _detailsView.Close();
                _detailsView = null;
                LoadData();
            }
        }
        #endregion
    }
}
